
import { DockAlign } from "./DockAlign";
import { DockType } from "./DockType";
import type { Solution } from "./Solution";
import type { ViewPlace } from "./ViewPlace";
export interface IRect {
  x: number;
  y: number;
  w: number;
  h: number;
}
export interface IPoint {
  x: number;
  y: number;
}
export interface ICallbacks<View = any, ViewData = any> {
  /**
   * View位置变化回调
   * 
   * 以下函数执行成功将触发本回调
   *    Solution::dock
   *    Solution::maximize
   *    Solution::restore
   *    Solution::minimize
   * 
   * 注意，直接调用Solution::set_view_place不会触发本回调。
   * 
   * @param view 变化的view
   * @param place 新位置
   * @param prev 原位置
   */
  on_place_changed?(view: View, place: ViewPlace, prev: ViewPlace): void;

  /**
   * View矩形变化回调
   * 
   * 以下函数执行成功将触发本回调
   * 
   * 注意，直接调用Solution::set_rect或IBridging::set_rect 不会触发本回调。
   * 
   * @param view 变化的view
   * @param place 新矩形
   * @param prev 原矩形
   */
  on_rect_changed?(view: View, rect: IRect, prev: IRect, solution: Solution<View, ViewData>): void;

  on_add?(view: View, solution: Solution<View, ViewData>): void;
  on_del?(view: View, solution: Solution<View, ViewData>): void;
  on_drag_begin?(view: View, solution: Solution<View, ViewData>): void;
  on_drag_end?(view: View, solution: Solution<View, ViewData>): void;
  on_add?(view: View, solution: Solution<View, ViewData>): void;
  on_del?(view: View, solution: Solution<View, ViewData>): void;

  on_dock_align_changed?(align: DockAlign, prev: DockAlign, solution: Solution<View, ViewData>): void;
  on_dock_type_changed?(type: DockType, prev: DockType, solution: Solution<View, ViewData>): void;
}

export interface IBridging<View = any> extends ICallbacks<View> {
  get_solution(): Solution<View> | undefined | null;
  set_solution(solution: Solution<View> | undefined | null): void;
  set_rect(view: View, rect: IRect): void;
  get_rect(view: View): IRect;
  get_pos(view: View): IPoint;
  set_pos(view: View, pos: IPoint): void;
  set_opacity(view: View, o: number): void;
  get_z(view: View): number;
  set_z(view: View, z: number): void;
  is_place_ok(view: View, place: ViewPlace): boolean;
}

export class BaseBridging<View = any> implements IBridging<View> {
  protected _solution?: Solution<View> | null;
  get_solution(): Solution<View> | null | undefined {
    return this._solution
  }
  set_solution(solution: Solution<View> | null | undefined): void {
    this._solution = solution
  }
  on_add(view: View): void { }
  on_del(view: View): void { }
  set_rect(view: View, rect: IRect): void { }
  get_rect(view: View): IRect { return { x: 0, y: 0, w: 0, h: 0 }; }
  get_pos(view: View): IPoint { return { x: 0, y: 0 }; }
  set_pos(view: View, pos: IPoint): void { }
  set_opacity(view: View, o: number): void { }
  get_z(view: View): number { return 0; }
  set_z(view: View, z: number): void { }
  on_drag_begin(view: View): void { }
  on_drag_end(view: View): void { }
  is_place_ok(view: View, place: ViewPlace): boolean { return false; }
  on_place_changed(view: View, place: ViewPlace, prev: ViewPlace): void { }
  on_rect_changed(view: View, rect: IRect, prev: IRect): void { }
  static inst = new BaseBridging();
}
